package com.atguign.gulimall.ware.listener;

import com.atguign.gulimall.ware.dao.WareSkuDao;
import com.atguign.gulimall.ware.entity.WareOrderTaskDetailEntity;
import com.atguign.gulimall.ware.entity.WareOrderTaskEntity;
import com.atguign.gulimall.ware.feign.OrderFeifnService;
import com.atguign.gulimall.ware.service.WareOrderTaskDetailService;
import com.atguign.gulimall.ware.service.WareOrderTaskService;
import com.atguigu.common.to.mq.OrderTo;
import com.atguigu.common.to.mq.StockLockedTo;
import com.atguigu.common.utils.R;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;

@Slf4j
@Service
@RabbitListener(queues = "stock.release.stock.queue")
public class StockReleaseListener {
    @Autowired
    OrderFeifnService orderFeifnService;
    @Autowired
    WareOrderTaskDetailService orderTaskDetailService;
    @Autowired
    WareOrderTaskService orderTaskService;
    @Autowired
    WareSkuDao wareSkuDao;
    /**
     * 解锁库存（库存自动解锁）
     * @param to
     */
    @RabbitHandler
    @Transactional
    public void handleStockLockedRelease(StockLockedTo to, Message message, Channel channel) throws IOException {
        log.debug("解锁库存（库存自动解锁）");
        WareOrderTaskDetailEntity byId = orderTaskDetailService.getById(to.getDeatail().getId());
        WareOrderTaskEntity taskEntity = orderTaskService.getById(to.getId());
        if(byId != null){
            R orderStatus = orderFeifnService.getOrderStatus(taskEntity.getOrderSn());
            if(orderStatus.getCode() == 0){
                Integer status = new Integer(orderStatus.get("data").toString());
                //订单状态为已锁定，解锁库存
                if(status == 4){
                    Long l = unLockStock(to.getDeatail().getSkuId(), to.getDeatail().getWareId(), to.getDeatail().getSkuNum(), to.getDeatail().getId());
                    //订单取消了
                    if(l==1L){
                        //订单回滚成功
                        log.debug("订单回滚成功");
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                    }else if(l==2L){
                        log.debug("解锁库存失败,订单不存在或订单已经解锁");
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                    }else{
                        log.error("解锁库存失败");
                        throw new RuntimeException("解锁库存失败");
                    }
                }
            }else{
                log.error("远程服务失败");
                throw new RuntimeException("远程服务失败");
            }
        }else{
            log.debug("没有查询到订单回滚");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }

    }

    private Long unLockStock(Long skuId, Long wareId, Integer num, Long taskDetailId) {
        WareOrderTaskDetailEntity byId = orderTaskDetailService.getById(taskDetailId);
        if(byId == null|| byId.getLockStatus() != 1){
            return 2L;
        }
        boolean update = orderTaskDetailService.update(new LambdaUpdateWrapper<WareOrderTaskDetailEntity>().set(WareOrderTaskDetailEntity::getLockStatus, 2)
                .eq(WareOrderTaskDetailEntity::getId, taskDetailId)
                .eq(WareOrderTaskDetailEntity::getLockStatus, 1));
        if(!update){
            return 0L;
        }
        return wareSkuDao.unLockStock(skuId, wareId, num);
    }

    /**
     * 解锁库存(订单超时主动解锁)
     * @param to
     * @param message
     * @param channel
     */
    @RabbitHandler
    @Transactional
    public void handleOrderCloseRelease(OrderTo to, Message message, Channel channel) throws IOException {
        log.debug("解锁库存(订单超时主动解锁)");
        int ok=0;
        R orderStatus = orderFeifnService.getOrderStatus(to.getOrderSn());
        if(orderStatus.getCode() == 0){
            Integer status = new Integer(orderStatus.get("data").toString());
            //订单状态为已锁定，解锁库存
            if(status == 4){
                WareOrderTaskEntity one = orderTaskService.getOne(new LambdaQueryWrapper<WareOrderTaskEntity>()
                        .eq(WareOrderTaskEntity::getOrderSn, to.getOrderSn()));
                List<WareOrderTaskDetailEntity> list = orderTaskDetailService.list(new LambdaQueryWrapper<WareOrderTaskDetailEntity>()
                        .eq(WareOrderTaskDetailEntity::getTaskId, one.getId())
                        .eq(WareOrderTaskDetailEntity::getLockStatus, 1));
                ok=list.size();
                for (WareOrderTaskDetailEntity wareOrderTaskDetailEntity : list) {
                    Long l = unLockStock(wareOrderTaskDetailEntity.getSkuId(), wareOrderTaskDetailEntity.getWareId(), wareOrderTaskDetailEntity.getSkuNum(), wareOrderTaskDetailEntity.getId());
                    if(l==1L){
                        ok--;
                    }
                }
            }
        }
        if(ok==0){
            log.debug("库存解锁成功");
            channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
        }else{
            log.error("库存解锁失败");
            throw new RuntimeException("库存解锁失败");
        }


    }


}
